<template>
    <div class="figuresContainer">
        <div class="carouselContainer" ref="container">
            <!-- 翻页容器 -->
            <div
                class="pageWrapper"
                :style="{
                    transform: `translateX(${totalOffset}px)`,
                    transition: isTransitioning? `transform ${animationDuration}ms ${easingFunction}` : 'none'
                }"
                @mousedown="startDrag"
                @mousemove="onDrag"
                @mouseup="endDrag"
                @mouseleave="endDrag"
                @touchstart="startDrag"
                @touchmove="onDrag"
                @touchend="endDrag"
            >
                <div
                    v-for="(page, pageIndex) in figurePages"
                    :key="`page-${pageIndex}`"
                    class="figurePage"
                >
                    <div
                        v-for="item in page"
                        :key="`figure-${item.id}`"
                        class="figureCard"
                    >
                        <div class="figureTop">
                            <img class="figureImg" :src="item.pic" alt="" draggable="false"/>
                        </div>
                        <div class="figureBottom">
                            <h2>{{ item.title }}</h2>
                            <p>{{ item.description }}</p>
                        </div>
                    </div>
                </div>
            </div>

            <img
                v-show="!isFirstPage"
                class="prePageBtn"
                src="/src/assets/img/common/carouselArrow.webp"
                alt=""
                @click="prePage"
            />
            <img
                v-show="!isLastPage"
                class="nextPageBtn"
                src="/src/assets/img/common/carouselArrow.webp"
                alt=""
                @click="nextPage"
            />

            <div class="dotGroup">
                <span
                    v-for="(dot, dotIndex) in totalDots"
                    :key="`dot-${dotIndex}`"
                    class="dot"
                    :class="{ active: dotIndex === currentPage }"
                    @click="goToPage(dotIndex)"
                ></span>
            </div>
        </div>
    </div>
</template>

<script setup>
import {reactive, ref, computed} from 'vue';

const figures = reactive([
    {
        id: '001',
        pic: '/src/assets/img/careers/index/figure01.webp',
        title: 'Sheila, Marketing',
        description: '"As I reflect, I realise that being a minority has never deterred me from my work. Something that perhaps speaks on the kind of progressive work culture Supercell has had from the beginning. Even though we are still working towards being a diverse company, your skills, talents and work matter more."'
    },
    {
        id: '002',
        pic: '/src/assets/img/careers/index/figure02.webp',
        title: 'Camilla, Game Designer',
        description: '"What I enjoy about Supercell is being truly responsible for my work and putting out quality games together with a great team that also gives their best. I feel respected and trusted. The acknowledgement of the importance of work-life balance creates opportunities for fun times with really good colleagues."'
    },
    {
        id: '003',
        pic: '/src/assets/img/careers/index/figure03.webp',
        title: 'Stuart, Game Programmer',
        description: '"I like being able to decide what to work on with my team and then just do it without having to seek approval or permission from anyone else. Everyone in the company plays at least one of our games passionately. The best players of a certain game might work in marketing or finance instead of a game team."'
    },
    {
        id: '004',
        pic: '/src/assets/img/careers/index/figure04.webp',
        title: 'Alexander, Recruitment',
        description: '"Congratulations, you clicked/tapped the arrow that took you to this page of this carousel webpage element. Working in recruitment, I have no choice but to tell you that Supercell is the workplace of your dreams. It\'s almost an illusion of how close to ideal this place is as a work environment. If you\'re not die - hardly adamant about being an actual entrepreneur or freelancer, this is the second best thing for you to do."'
    }
]);

const currentPage = ref(0);
const container = ref(null);
const dragStartX = ref(0);
const dragDelta = ref(0);
const totalOffset = ref(0);
const isDragging = ref(false);
const isTransitioning = ref(false);
const dragThreshold = ref(30);
const animationDuration = 300;
const easingFunction = 'cubic-bezier(0.25, 0.46, 0.45, 0.94)';

const figuresPerPage = 2;

const figurePages = computed(() => {
    const pages = [];
    for (let i = 0; i < figures.length; i += figuresPerPage) {
        pages.push(figures.slice(i, i + figuresPerPage));
    }
    return pages;
});

const totalPages = computed(() => figurePages.value.length);
const totalDots = computed(() => totalPages.value);
const isFirstPage = computed(() => currentPage.value === 0);
const isLastPage = computed(() => currentPage.value === totalPages.value - 1);
const pageWidth = () => container.value?.clientWidth || window.innerWidth;

const startDrag = (e) => {
    isDragging.value = true;
    dragStartX.value = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX;
    dragDelta.value = 0;
    isTransitioning.value = false;
};

const onDrag = (e) => {
    if (!isDragging.value) return;
    const currentX = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX;
    const delta = currentX - dragStartX.value;
    dragDelta.value = delta;
    totalOffset.value = -currentPage.value * pageWidth() + delta;
};

const endDrag = () => {
    if (!isDragging.value) return;
    isDragging.value = false;
    const delta = dragDelta.value;
    const pageWidthVal = pageWidth();

    if (Math.abs(delta) < dragThreshold.value) {
        smoothScrollTo(pageWidthVal * currentPage.value);
        return;
    }

    const scrollRatio = delta / pageWidthVal;
    let targetPage = currentPage.value;

    if (delta > 0 && !isFirstPage.value) {
        targetPage = scrollRatio > 0.3 ? currentPage.value - 1 : currentPage.value;
    } else if (delta < 0 && !isLastPage.value) {
        targetPage = scrollRatio < -0.3 ? currentPage.value + 1 : currentPage.value;
    } else {
        bounceWithVelocity(delta);
        return;
    }

    smoothScrollTo(pageWidthVal * targetPage);
    currentPage.value = targetPage;
};

const smoothScrollTo = (targetX) => {
    isTransitioning.value = true;
    totalOffset.value = -targetX;
    const transitionStyle = `transform ${animationDuration}ms ${easingFunction}`;
    const wrapper = container.value?.querySelector('.pageWrapper');
    wrapper.style.transition = transitionStyle;

    setTimeout(() => {
        isTransitioning.value = false;
        wrapper?.removeAttribute('style');
    }, animationDuration);
};

const bounceWithVelocity = (delta) => {
    const velocity = delta / 100;
    const bounceDistance = Math.min(Math.abs(velocity) * 80, 100);

    isTransitioning.value = true;
    totalOffset.value += isFirstPage.value ? bounceDistance : -bounceDistance;

    setTimeout(() => {
        totalOffset.value = -currentPage.value * pageWidth();
        setTimeout(() => {
            isTransitioning.value = false;
        }, animationDuration);
    }, 100);
};

const prePage = () => {
    if (isFirstPage.value) {
        bounceWithVelocity(-100);
        return;
    }
    currentPage.value--;
    slideToCurrent();
};

const nextPage = () => {
    if (isLastPage.value) {
        bounceWithVelocity(100);
        return;
    }
    currentPage.value++;
    slideToCurrent();
};

const goToPage = (page) => {
    currentPage.value = page;
    slideToCurrent();
};

const slideToCurrent = () => {
    smoothScrollTo(pageWidth() * currentPage.value);
};
</script>

<style scoped>
.carouselContainer {
    position: relative;
    overflow: hidden;
    margin-bottom: 30px;
}

.pageWrapper {
    display: flex;
    will-change: transform;
}

.figurePage {
    flex-shrink: 0;
    width: 100%;
    padding: 50px 3%;
    display: flex;
    justify-content: space-between;
}

.figureCard {
    flex-basis: calc(50% - 20px);
    box-shadow: 0 8px 28px -6px rgb(0, 0, 0, 0.2);
    border: 1px solid #f0f0f0;
    margin-bottom: 40px;
    transition: all 0.3s ease-in-out;
}

.figureTop {
    position: relative;
}

.figureImg {
    width: 100%;
    user-select: none;
}

.figureBottom {
    padding: 37px 60px 13px 60px;
    user-select: none;
}

.figureBottom h2 {
    font-size: 20px;
    margin-bottom: 20px;
}

.figureBottom p {
    font-size: 16px;
    line-height: 1.5;
}

.prePageBtn,
.nextPageBtn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 4%;
    cursor: pointer;
    -webkit-user-drag: none;
}

.prePageBtn {
    left: 0;
}

.nextPageBtn {
    right: 0;
    transform: translateY(-50%) rotateY(180deg);
}

.dotGroup {
    position: absolute;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 10px;
}

.dot {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background-color: #ccc;
    cursor: pointer;
}

.dot.active {
    background-color: #2d85f3;
    width: 24px;
    border-radius: 7px;
    transition: width 0.3s ease-in-out;
}
</style>